package suncertify.Server;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import suncertify.db.DbExceptions.RecordNotFoundException;
import suncertify.db.Data;
import suncertify.shared.ServerBroker;
import suncertify.shared.ServerProperty;

/**
 *
 * @author jshah
 * Implements the ServerBroker Interface to provide a wrapper to Data class which contains Remote Methods
 */
public class ServerBrokerImplementation extends UnicastRemoteObject implements ServerBroker{

    

    Data rmanager;

    /**
     * Default Constructor which creates a RemoteObject
     * @throws RemoteException          throws RemoteException if there is an error creating UnicastRemoteObject
     */
    public ServerBrokerImplementation() throws RemoteException{

    }

    /**
     * Supplies the database path and creates a <code>Data</code> instance with the given path
     * @return     returns true on successful instantiation of a <code>Data</code> instance with the given path, false if not able to create a <code>Data</code> instance
     */
    public boolean setDbPath(){
          try{

                 //for RMI mode the dbfile is whatever is selected during server configuration user has no say on which dbfile to use
                 String rfile = ServerProperty.getServerDBFileProp();
                 System.out.println(rfile);
                 this.rmanager = new Data(rfile,"rw");
	    }
	    catch(IOException ioE){

			Logger.getLogger(ServerBrokerImplementation.class.getName()).log(Level.SEVERE, "DB FILE NOT FOUND", ioE);
                        return false;
            }

            return true;
     }

     /**
      * Function which calls appropriate method in <code>Data</code> to search records from the db file
      * @param name             String representing the desired value of the "Name" field in the records
      * @param Location         String representing the desired value of the "Location" field in the records
      * @return                 returns the list of all the records
      */
     public ArrayList<String[]> searchRecords(String name, String Location) {

               
                String[] criteria = {name,Location};
                int[] found = rmanager.find(criteria);
                if(found == null)
                    return null;
                ArrayList<String[]> dataRows = new ArrayList<String[]>();
                for(int i: found){
                try {
                        dataRows.add(rmanager.read(i));
                    } catch (RecordNotFoundException ex) {
                             Logger.getLogger(ServerBrokerImplementation.class.getName()).log(Level.SEVERE, "RECORD DOES NOT EXIST", ex);
                             return null;
                    }
                }
                return dataRows;
     }


    /**
     * Supplies a customer id String which is "4digit number" to indicate customer currently hiring the contractor
     * @param recNo                      recNo of the record in the dbfile
     * @param customerID                 A four digit customer ID string unique to each custormer(it is assumed that customer provides this to the CSR)
     * @return                           returns a String to notify wether a booking was successful or if not then returns a message corresponding to the ERRORCODE indicating the reason                                      '
     */
    public String book(int recNo, String customerID){

        byte retCode = rmanager.book(recNo, customerID);

        switch (retCode){
            case 0:
                return "BOOKING SUCCESSFUL";
            case Data.SECURITYERROR:
                return "RECORD IS LOCKED BY ANOTHER CSR TRY LATER";
            case Data.RECNOTFOUND:
                return "RECORD NOT FOUND, IT MIGHT BE DELETED";
            default:
                return "UNKNOWN ERROR, RECORD NOT BOOKED";
        }

    }

    /**
     * unbooks by clearing the customer id in the owned by column of the record in dbfile
     * @param recNo          record no. of the record which needs to unbooked
     * @return              returns a string message representing wether it was a success or the type of error
     */
    public String unbook(int recNo){
        byte errorcode =  rmanager.unbook(recNo);

        switch(errorcode){
            case 0:
                return "RECORD SUCCESSFULLY UNBOOKED";
            case Data.RECNOTFOUND:
                return "RECORD NOT FOUND, IT MIGHT BE DELETED";
            case Data.INVALIDBOOKING:
                return "RECORD SHOULD BE BOOKED FIRST TO UNBOOK";
            case Data.SECURITYERROR:
                return "RECORD IS LOCKED BY ANOTHER CSR TRY LATER";
            default:
                return "UNKNOWNERROR OCCURED,RECORD NOT UNBOOKED";
        }
    }

    /**
     * Calls the read method of <code>Data</code> to return a <code>String[]</code> containing the contents of record
     * @param recNo         the number of the record whose contents are requested
     * @return              <code>String[]</code> containing the contents of record where each elements represents a field of the record, returns <code>null</code> if record not found
     */
    public String[] read(int recNo) {

        try{
            return rmanager.read(recNo);
        }
        catch(RecordNotFoundException e){
            Logger.getLogger(ServerBrokerImplementation.class.getName()).log(Level.SEVERE, "RECORD DOES NOT EXIST", e);
            return null;
        }
    }

   
      
       
   }

